package com.lanhai.utils;

import java.math.BigInteger;

/**
 * byte数组与16进制字符串的转换工具
 * @author liangmin
 *
 */
public class HexUtil {
	/**
	 * 判别A字符串是否包含字符串B
	 *
	 * @param message
	 *            A字符串
	 * @param detailbyte2HexStr
	 *            字符串B
	 * @return
	 */
	public static boolean contain(String message, String detail) {

		if (message.indexOf(detail) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * crc16检测
	 *
	 * @param data
	 * @return
	 */
	private static int[] crcInt(int[] data) {
		int[] temdata = new int[data.length + 2];
		// unsigned char alen = *aStr 鈥?2; //CRC16鍙绠楀墠涓ら儴鍒?
		int xda, xdapoly;
		int i, j, xdabit;
		xda = 0xFFFF;
		xdapoly = 0xA001; // (X**16 + X**15 + X**2 + 1)
		for (i = 0; i < data.length; i++) {
			xda ^= data[i];
			for (j = 0; j < 8; j++) {
				xdabit = (int) (xda & 0x01);
				xda >>= 1;
				if (xdabit == 1)
					xda ^= xdapoly;
			}
		}
		System.arraycopy(data, 0, temdata, 0, data.length);
		temdata[temdata.length - 2] = (int) (xda & 0xFF);
		temdata[temdata.length - 1] = (int) (xda >> 8);
		return temdata;
	}

	/**
	 * 二次crc16检测
	 *
	 * @param data
	 * @return
	 */
	public static byte[] crc16(int[] data) {
		// 获取临时的crc数据
		int[] tempData = crcInt(data);
		// 定义发送的数据
		byte[] dataByte = new byte[tempData.length + 2];
		dataByte[0] = (byte) 0xA1;
		dataByte[dataByte.length - 1] = (byte) 0xB0;
		for (int i = 0; i < tempData.length; i++) {
			dataByte[i + 1] = (byte) tempData[i];
		}
		return dataByte;
	}

	public static void main(String[] args){
		byte[] bArr = {-95, 1, 1, 0, 0, 0, 1, -95};
		
		
		System.out.println(HexUtil.byte2HexStr(bArr));
		String plcNo = "118";
		String servNo = "40";
		byte[] sendByte = new byte[18];
        //command frame header
        sendByte[0] = (byte)0x80;//ICF
        sendByte[1] = (byte)0x00;//RSV
        sendByte[2] = (byte)0x02;//GCT, less than 8 network layers
        sendByte[3] = (byte)0x00;//DNA, local network
        sendByte[4] = CommandUtil.toLH(Integer.parseInt(plcNo))[0];//DA1(PLC网络号)
        sendByte[5] = (byte)0x00;//DA2, CPU unit
        sendByte[6] = (byte)0x00;//SNA, local network
        sendByte[7] = CommandUtil.toLH(Integer.parseInt(servNo))[0];//SA1(PC网络号)
        sendByte[8] = (byte)0x00;//SA2, CPU unit
        sendByte[9] = (byte)0x00;//SID
        sendByte[10] = (byte)0x01;//MRC
        sendByte[11] = (byte)0x01;//SRC(读:1，写:2)
        sendByte[12] = hexToByte("82")[0];//固定
        int x = 100;
        sendByte[13] = CommandUtil.toLH(x)[1];//寄存器地址高位
        sendByte[14] = CommandUtil.toLH(x)[0];//寄存器地址低位
        sendByte[15] = (byte)0x00;//固定
        sendByte[16] = (byte)0x00;//读取数量高位
        sendByte[17] = (byte)0x01;//读取数量低位
        
		byte[] hArr = CommandUtil.toHH(x);
		System.out.println(HexUtil.byte2HexStr(hArr));
		System.out.println(HexUtil.byte2HexStr(sendByte));
	}

	/**
     * hex转byte数组
     * @param hex
     * @return
     */
    public static byte[] hexToByte(String hex){
        int m = 0, n = 0;
        int byteLen = hex.length() / 2; // 每两个字符描述一个字节
        byte[] ret = new byte[byteLen];
        for (int i = 0; i < byteLen; i++) {
            m = i * 2 + 1;
            n = m + 1;
            int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
            ret[i] = Byte.valueOf((byte)intVal);
        }
        return ret;
    }
	
	/**
	 * bytes转字符串字节转换为字符串样式
	 */
	public static String byte2HexStr(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
			// if (n<b.length-1) hs=hs+":";
		}
		return hs.toUpperCase();
	}
	

	/**
	 * bytes转字符串字节转换为字符串样式
	 */
	public static String byte2HexStr(byte[] b, int begin, int end) {
		String hs = "";
		String stmp = "";
		for (int n = begin; n < end; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
			// if (n<b.length-1) hs=hs+":";
		}
		return hs.toUpperCase();
	}

	/**
	 * 检校和
	 *
	 * @param data
	 * @param len
	 * @return
	 */
	public static boolean checkAddDatas(byte[] data) {
		byte allCost = 0;
		for (int i = 0; i < data.length - 1; i++) {
			allCost += data[i];
		}

		// 不等处理
		if (allCost != data[data.length - 1]) {
			return false;
		}
		return true;
	}
	
	/**
	 * 16进制字符串转10进制int
	 * @param hexs
	 * @return
	 */
	public static int decodeHEX(String hexs){
		BigInteger bigint=new BigInteger(hexs, 16);
		int numb=bigint.intValue();
		return numb;
	}

	//將10進制轉換為16進制
	public static String encodeHEX(Integer numb){		
		String hex= Integer.toHexString(numb);
		return hex;
		
	}	
	
}
